package v4_registry

import (
	"go-demo/orm/interval/errs"
	"reflect"
	"sync"
)

type registry struct {
	models sync.Map
}

// parseModel typ 仅支持一级结构体指针类型
func (r *registry) parseModel(typ reflect.Type) (*model, error) {
	if typ.Kind() != reflect.Ptr || typ.Elem().Kind() != reflect.Struct {
		return nil, errs.ErrPointerOnly
	}
	typ = typ.Elem()
	numField := typ.NumField()
	fds := make(map[string]*field, numField)
	for i := 0; i < numField; i++ {
		fdType := typ.Field(i)
		fds[fdType.Name] = &field{
			colName: underscoreName(fdType.Name),
		}
	}
	return &model{
		tableName: underscoreName(typ.Name()),
		fieldMap:  fds,
	}, nil
}

func (r *registry) get(entity any) (*model, error) {
	typ := reflect.TypeOf(entity)
	data, ok := r.models.Load(typ)
	if ok {
		return data.(*model), nil
	}
	m, err := r.parseModel(typ)
	if err != nil {
		return nil, err
	}
	r.models.Store(typ, m)
	return m, nil
}
